package com.risenetsoft.elasticsearch.api;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.avg.Avg;
import org.elasticsearch.search.aggregations.metrics.avg.AvgAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.max.Max;
import org.elasticsearch.search.aggregations.metrics.max.MaxAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.min.Min;
import org.elasticsearch.search.aggregations.metrics.min.MinAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.percentiles.*;
import org.elasticsearch.search.aggregations.metrics.stats.Stats;
import org.elasticsearch.search.aggregations.metrics.stats.StatsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.stats.extended.ExtendedStats;
import org.elasticsearch.search.aggregations.metrics.stats.extended.ExtendedStatsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.aggregations.metrics.sum.SumAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount;
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCountAggregationBuilder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * Created by Zhanggd on 2017/8/9.
 */
public class AggregationMetricDemo {
    public static final String CLUSTER_NAME = "elasticsearch"; //实例名称
    private static final int PORT = 9300;  //端口
    private static final String IP = "192.168.190.104";
    private static Settings settings = Settings.builder()
            .put("cluster.name",CLUSTER_NAME)
            .put("client.transport.sniff",true)
            .put("client.transport.ping_timeout","120s")
            .build();

    private static TransportClient client;
    static {
        try {
            client = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(IP), PORT));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        minAggregate();

        maxAggregate();

        sumAggregate();

        avgAggregate();

        statsAggregate();

        extendedStatsAggregate();

        countAggregate();

        percentAggregate();

        percentRankeAggregate();
    }


    /**
     * 计算最新值
     */
    public static void minAggregate(){
        MinAggregationBuilder aggregation = AggregationBuilders.min("agg").field("price");
        SearchResponse searchResponse = client.prepareSearch("my_store")//my_store为索引
                .addAggregation(aggregation).get();

        Min agg = searchResponse.getAggregations().get("agg");
        double value = agg.getValue();
        System.out.println("最低价格："+value);
    }

    /**
     * 计算最大值
     */
    public static void maxAggregate(){
        MaxAggregationBuilder aggregation = AggregationBuilders.max("agg").field("price");
        SearchResponse searchResponse = client.prepareSearch("my_store")
                .addAggregation(aggregation).get();

        Max agg = searchResponse.getAggregations().get("agg");
        double value = agg.getValue();
        System.out.println("最高价格："+value);

    }

    /**
     * 求和
     */
    public static void sumAggregate(){
        SumAggregationBuilder aggregation = AggregationBuilders.sum("agg").field("price");

        SearchResponse searchResponse = client.prepareSearch("my_store")
                .addAggregation(aggregation).get();

        Sum agg = searchResponse.getAggregations().get("agg");
        double value = agg.getValue();
        System.out.println("总价格："+value);

    }

    /**
     * 计算平均值
     */
    public static void avgAggregate(){
        AvgAggregationBuilder aggregation = AggregationBuilders.avg("avg").field("price");
        SearchResponse searchResponse = client.prepareSearch("my_store")
                .addAggregation(aggregation).get();

        Avg avg = searchResponse.getAggregations().get("avg");
        double vaule = avg.getValue();
        System.out.println("平均价格为："+vaule);
    }

    /**
     * 获取统计信息
     */
    public static void statsAggregate(){
        StatsAggregationBuilder aggregation = AggregationBuilders.stats("stats").field("price");
        SearchResponse searchResponse = client.prepareSearch("my_store")
                .addAggregation(aggregation).get();

        Stats stats = searchResponse.getAggregations().get("stats");
        double min = stats.getMin();
        double max = stats.getMax();
        double sum = stats.getSum();
        double avg = stats.getAvg();
        long count = stats.getCount();
        System.out.println("===============stats==================");
        System.out.println("最低价格:"+min);
        System.out.println("最高价格:"+max);
        System.out.println("总价格:"+sum);
        System.out.println("平均价格:"+avg);
        System.out.println("总记录:"+count);
    }

    private static void extendedStatsAggregate() {
        ExtendedStatsAggregationBuilder aggregation = AggregationBuilders.extendedStats("extendedStats").field("price");
        SearchResponse searchResponse = client.prepareSearch("my_store")
                .addAggregation(aggregation).get();

        ExtendedStats stats = searchResponse.getAggregations().get("extendedStats");
        double min = stats.getMin();
        double max = stats.getMax();
        double sum = stats.getSum();
        double avg = stats.getAvg();
        long count = stats.getCount();
        System.out.println("===============extendedStats==================");
        System.out.println("最低价格:"+min);
        System.out.println("最高价格:"+max);
        System.out.println("总价格:"+sum);
        System.out.println("平均价格:"+avg);
        System.out.println("总记录:"+count);
    }

    /**
     * 统计记录
     */
    public static void countAggregate(){
        ValueCountAggregationBuilder aggregation = AggregationBuilders.count("count").field("price");
        SearchResponse searchResponse = client.prepareSearch("my_store")
                .addAggregation(aggregation).get();

        ValueCount count = searchResponse.getAggregations().get("count");
        long value = count.getValue();
        System.out.println("记录数："+value);

    }

    /**
     * 百分比
     */
    public static void percentAggregate(){
        PercentilesAggregationBuilder aggregation = AggregationBuilders.percentiles("percent").field("height")
                .percentiles(1.0, 5.0, 10.0, 20.0, 30.0, 75.0, 95.0, 99.0);

        SearchResponse searchResponse = client.prepareSearch("my_store").addAggregation(aggregation).get();

        Percentiles percentiles = searchResponse.getAggregations().get("percent");
        for(Percentile entry:percentiles){
            double percent = entry.getPercent();
            double value = entry.getValue();
            System.out.println("["+percent+"] ,["+value+"]");
        }

    }

    public static void percentRankeAggregate(){
        PercentileRanksAggregationBuilder aggregation = AggregationBuilders.percentileRanks("ranks")
                .field("price").values(1.24, 1.91, 2.22);;
        SearchResponse searchResponse = client.prepareSearch("my_store").addAggregation(aggregation).get();

        PercentileRanks ranks = searchResponse.getAggregations().get("ranks");
        for(Percentile entry:ranks){
            double percent = entry.getPercent();
            double value = entry.getValue();
            System.out.println("["+percent+"] ,["+value+"]");
        }
    }

}
